<script setup lang="ts">
import type { CalendarInstance } from 'element-plus'
import { CircleCheckFilled, CircleCloseFilled, UserFilled } from '@element-plus/icons-vue'
import { assign, debounce } from 'lodash-es'
import { addDays, format, isBefore, isEqual } from 'date-fns'
import TheApprovalFillDetail from './components/TheApprovalFillDetail.vue'

const calendarRef = ref<CalendarInstance>()
const selectedMonth = ref(new Date())

const selectedDates = ref<string[]>([])
function isSelected(date: string) {
  return selectedDates.value.includes(date)
}

const batchSelectRange = reactive({
  start: '',
  end: '',
})
watch(
  () => batchSelectRange,
  () => {
    // eslint-disable-next-line @typescript-eslint/no-use-before-define
    if (!isBatchSelecting.value || !batchSelectRange.start || !batchSelectRange.end) return

    const start = new Date(batchSelectRange.start)
    const end = new Date(batchSelectRange.end)

    let s: Date,
      e: Date
      // eslint-disable-next-line prefer-const
    ;[s, e] = isBefore(start, end) ? [start, end] : [end, start]

    const dates = new Set([s])
    let i = s
    while (!isEqual(i, e) && isBefore(i, e)) {
      i = addDays(i, 1)
      dates.add(i)
    }

    selectedDates.value = [...dates].map((date) => format(date, 'yyyy-MM-dd'))
  },
  { deep: true },
)

const [isBatchSelecting, toggleBatchSelect] = useToggle(false)
watch(isBatchSelecting, (value) => {
  if (!value) assign(batchSelectRange, { start: '', end: '' })
})
function handleDateDblclick(date: string) {
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  handleFill.cancel()
  toggleBatchSelect(true)
  batchSelectRange.start = date
  batchSelectRange.end = date
}
function handleDateMouseenter(date: string) {
  if (!isBatchSelecting.value) return
  batchSelectRange.end = date
}

// TODO: 待限制仅审批当月
function handleDateClick(date: string) {
  const isBatch = isBatchSelecting.value
  if (isBatch) toggleBatchSelect(false)
  else selectedDates.value = [date]

  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  handleFill()
}

const [showFillDialog, toggleShowFillDialog] = useToggle(false)
const handleFill = debounce(() => {
  toggleShowFillDialog(true)
}, 300)
</script>

<template>
  <ElCard class="card is-flex">
    <ElDialog
      v-model="showFillDialog"
      title="填报详情"
      width="80%"
      :append-to-body="true"
      :center="true"
      :destroy-on-close="true"
    >
      <TheApprovalFillDetail />
    </ElDialog>

    <ElCalendar
      ref="calendarRef"
      v-model="selectedMonth"
      class="calendar"
    >
      <template #header>
        <ElForm :inline="true">
          <ElFormItem label="日期">
            <ElDatePicker type="month" />
          </ElFormItem>
          <ElFormItem label="项目">
            <ElSelect :multiple="true">
              <ElOption value="code1">
                项目1
              </ElOption>
              <ElOption value="code2">
                项目2
              </ElOption>
            </ElSelect>
          </ElFormItem>
          <ElFormItem label="人员">
            <ElSelect :multiple="true">
              <ElOption value="user1">
                张三
              </ElOption>
              <ElOption value="user2">
                李四
              </ElOption>
            </ElSelect>
          </ElFormItem>
        </ElForm>

        <ElForm :inline="true">
          <ElFormItem label="总工时">
            <span>100 人天</span>
          </ElFormItem>
          <ElFormItem :label-width="0">
            <ElButton type="success">
              审批通过
            </ElButton>
            <ElButton type="danger">
              审批驳回
            </ElButton>
          </ElFormItem>
        </ElForm>
      </template>

      <template #date-cell="{ data }">
        <div
          class="calendar-cell-wrapper"
          :class="[{ 'is-selected': isSelected(data.day) }]"
        >
          <div
            class="calendar-cell"
            @click="handleDateClick(data.day)"
            @dblclick="handleDateDblclick(data.day)"
            @mouseenter="handleDateMouseenter(data.day)"
          >
            <div
              class="actions"
              @click.stop
              @dblclick.stop
            >
              <ElButtonGroup>
                <ElButton
                  type="success"
                  size="small"
                  :icon="CircleCheckFilled"
                />
                <ElButton
                  type="danger"
                  size="small"
                  :icon="CircleCloseFilled"
                />
              </ElButtonGroup>
            </div>
            <div class="text">
              <span>{{ +data.day.split('-').at(-1) }}</span>
            </div>

            <div
              v-show="+data.day.split('-').at(-1) > 10"
              class="users"
            >
              <ElAvatar
                v-for="item in 3"
                :key="item"
                size="small"
              >
                <ElIcon>
                  <UserFilled />
                </ElIcon>
              </ElAvatar>

              <ElAvatar size="small">
                <span style="transform: scale(0.6)">+13</span>
              </ElAvatar>
            </div>
          </div>
        </div>
      </template>
    </ElCalendar>
  </ElCard>
</template>

<style lang="scss" scoped>
.card {
  height: 100%;

  .top-area {
    display: flex;
    justify-content: space-between;
  }

  .calendar {
    --el-calendar-cell-width: 100px;

    :deep(.el-form-item:last-child) {
      margin-right: 0;
    }

    /* stylelint-disable-next-line */
    :deep(.el-calendar-table__row) {
      > td:first-child,
      > td:last-child {
        .status {
          color: var(--el-color-success);
        }
      }
    }

    :deep(.prev),
    :deep(.current),
    :deep(.next) {
      position: relative;
      z-index: 1;

      &.is-selected {
        background-color: transparent;
      }
    }

    .calendar-cell-wrapper {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: transparent;

      &.is-selected {
        background-color: var(--el-calendar-selected-bg-color);
      }
    }

    .calendar-cell {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      user-select: none;

      > :not(:first-child) {
        margin-top: 4px;
      }

      .actions {
        display: none;
        position: absolute;
        top: 10px;
        right: 10px;
      }

      &:hover {
        .actions {
          display: block;
        }
      }

      .text {
        position: relative;
        font-weight: 700;
      }

      .users {
        position: absolute;
        bottom: 10%;

        > * {
          float: left;
        }

        > :not(:first-child) {
          margin-left: -5%;
        }
      }
    }
  }
}
</style>

<route lang="json5">
{
  "meta": {
    "index": 1,
    "title": "工时审批",
  },
}
</route>
